package com.hcms.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.hcms.admin.dto.SysRolePermissionTreeResponse;
import com.hcms.admin.service.ISysMenuService;
import com.hcms.admin.service.ISysRolePermissionService;
import com.hcms.common.exception.ApiException;
import com.hcms.common.util.TreeUtil;
import com.hcms.mybatis.entity.SysMenu;
import com.hcms.mybatis.entity.SysRole;
import com.hcms.mybatis.entity.SysRolePermission;
import com.hcms.mybatis.mapper.SysRoleMapper;
import com.hcms.admin.service.ISysRoleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 后台用户角色表 服务实现类
 * </p>
 *
 * @author achenxw@126.com
 * @since 2023-02-14
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Autowired
    private ISysMenuService sysMenuService;

    @Autowired
    private ISysRolePermissionService sysRolePermissionRelationService;

    @Override
    public List<SysRole> getList(String keyword, Integer pageNum, Integer pageSize) {
        logger.info("Run getList(), keyword={}, pageNum={}, pageSize={}", keyword, pageNum, pageSize);
        PageHelper.startPage(pageNum, pageSize, "id DESC");
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        if (StrUtil.isNotEmpty(keyword)) {
            queryWrapper.like(SysRole::getName, keyword);
        }
        logger.info("Get a list of roles");
        return sysRoleMapper.selectList(queryWrapper);
    }

    @Override
    public SysRole getView(Long id) {
        return sysRoleMapper.selectById(id);
    }

    @Override
    public int createItem(SysRole role) {
        role.setCreateTime(new Date());
        return sysRoleMapper.insert(role);
    }

    @Override
    public int updateItem(Long id, SysRole role) {
        role.setId(id);
        return sysRoleMapper.updateById(role);
    }

    @Override
    public int deleteItem(String ids) {
        String[] split = ids.split(",");
        List<String> list = Arrays.asList(split);
        List<Long> collect = list.stream().map(Long::parseLong).collect(Collectors.toList());
        return sysRoleMapper.deleteBatchIds(collect);
    }

    @Override
    public List<SysRolePermissionTreeResponse> getRolePermissions(Long roleId) {
        logger.info("Run getRolePerm(), roleId={}", roleId);
        List<SysMenu> sysMenus = sysMenuService.getList();
        List<SysRolePermissionTreeResponse> list = sysMenus.stream().map(menu -> new SysRolePermissionTreeResponse(menu)).collect(Collectors.toList());
        return TreeUtil.builder(list, 0L);
    }

    @Override
    public boolean setRolePermissions(Long roleId, Collection<String> permissions) {
        logger.info("Run setRolePerm()");
        if (roleId <= 1) {
            throw new ApiException("该角色不可编辑");
        }
        List<String> oldPerm = sysRolePermissionRelationService.getPermissionsByRoleId(roleId);
        //批量删除记录
        HashSet<String> delPerm = new HashSet<>(oldPerm);
        delPerm.removeAll(permissions);
        if (delPerm.size() > 0) {
            LambdaQueryWrapper<SysRolePermission> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysRolePermission::getRoleId, roleId);
            queryWrapper.in(SysRolePermission::getPermission, delPerm);
            sysRolePermissionRelationService.remove(queryWrapper);
        }
        //批量添加记录
        HashSet<String> addPerm = new HashSet<>(permissions);
        oldPerm.forEach(addPerm::remove);
        if (addPerm.size() > 0) {
            Collection<SysRolePermission> entityList = addPerm.stream().map(perm -> {
                SysRolePermission relation = new SysRolePermission();
                relation.setRoleId(roleId);
                relation.setPermission(perm);
                return relation;
            }).collect(Collectors.toList());
            sysRolePermissionRelationService.saveBatch(entityList);
        }
        return true;
    }

}
